<script setup lang="ts">
// 扩展容器，可以将外层容器放大，而内部元素自适应，且放大的过程追加了过渡效果，
// 依据当前浏览器支持情况，可以选择 view transation 或者 animation transation
import { IBox } from "./inter"
import { ref, onMounted, unref } from "vue"
import { has } from "lodash-es"
import { useElementBounding,useScrollLock } from "@vueuse/core"
//
const props = withDefaults(defineProps<IBox.ZoomProps>(), {
    showOperate: true,
    useAnimationApi: false,
})
//
const { width, height, top, left, useAnimationApi } = props;
//
const boxRef = ref<HTMLDivElement>();
const mainRef = ref<HTMLDivElement>();
//
const mainSize = useElementBounding(boxRef)
// 判断是否可以使用 view transation api
// @ts-ignore
const isViewApi = useAnimationApi ? false : document.startViewTransition != undefined;
const isZoomBig = ref(false)
//
const sl = useScrollLock(document.body);
// transation api  Animation 对象
let animateObj: Animation | undefined = undefined
let isPlayed = false;
let vt:any = undefined
//
// 缩小
const handleSamll = () => {
    if (isViewApi) {
        // @ts-ignore
        mainRef.value.style.viewTransitionName = 'content'
        // @ts-ignore
        vt = document.startViewTransition(() => {
            mainRef.value && (mainRef.value.className = "_content")
        })
        vt.finished.then(() => {
            sl.value = false;
            isZoomBig.value = false;
            // @ts-ignore
            mainRef.value.style.viewTransitionName = 'none'
        })
    } else {
        if (unref(isZoomBig)) {
            animateObj?.reverse();
        }
    }
}
// 放大
const handleLarge = () => {
    
    sl.value = true;
    if (isViewApi) {
        // @ts-ignore
        mainRef.value.style.viewTransitionName = 'content'
        // @ts-ignore
        vt = document.startViewTransition(() => {
            // @ts-ignore
            mainRef.value.className = "_content _zoom-big"
        })

        vt.finished.then(() => {
            isZoomBig.value = true;
            // @ts-ignore
            mainRef.value.style.viewTransitionName = 'none'
        })
    }
    // 当需要用 animation api 时，执行下面的逻辑
    else {
        // 初始化初始变量
        changeCurrentBoxCssVars();
        isPlayed == false && animateObj?.play();
        if (isPlayed) {
            if (!unref(isZoomBig)) {
                animateObj?.reverse()
            }
        }
        isPlayed = true;
    }
}

const handleAnimateFinish = () => {
    isZoomBig.value = !isZoomBig.value;
    if(isZoomBig.value == false){
        sl.value = false;
        // isPlace.value = false;
    } 
}

const changeCurrentBoxCssVars = () => {
    if (unref(mainSize)) {
        boxRef.value?.style.setProperty('--cw', `${unref(mainSize.width)}px`)
        boxRef.value?.style.setProperty('--ch', `${unref(mainSize.height)}px`)
        boxRef.value?.style.setProperty('--ct', `${unref(mainSize.top)}px`)
        boxRef.value?.style.setProperty('--cl', `${unref(mainSize.left)}px`)
    }
}
//
onMounted(() => {
    // @ts-ignore
    console.log(mainSize, width, document.startViewTransition, has(document, 'startViewTransition'))
    //
    if (width) { boxRef.value?.style.setProperty('--mw', width) }
    if (height) { boxRef.value?.style.setProperty('--mh', height) }
    if (top) { boxRef.value?.style.setProperty('--top', top) }
    if (left) { boxRef.value?.style.setProperty('--left', left) }
    //
    changeCurrentBoxCssVars();
    if (!isViewApi) {
        //
        animateObj = unref(mainRef)?.getAnimations()?.[0]
        if (animateObj) {
            animateObj.onfinish = handleAnimateFinish
        }
    }
})

</script>

<template>
    <div ref="boxRef" class="box-zoom" relative w-full h-full overflow-hidden>
        <!-- 内容容器 -->
        <div ref="mainRef" :class="['_content',{'_animate':!isViewApi}]" relative w-full h-full>
            <slot></slot>
            <div v-if="showOperate" class="_operate" bg-white absolute right-8px top-8px flex flex-col gap-4px z-99 p-4px rd-4>
                <i v-if="isZoomBig" class="i-ic:round-zoom-in-map btn" title="缩小" cursor-pointer w-1em h-1em
                    @click="handleSamll"></i>
                <i v-else class="i-ic:round-zoom-out-map btn" title="放大" cursor-pointer w-1em h-1em
                    @click="handleLarge"></i>
                <slot name="operate"></slot>
            </div>
        </div>
    </div>
</template>

<style scoped>
::view-transition-old(content),
::view-transition-new(content) {
    animation: none;
}

.box-zoom {
    --mw: 80vw;
    --mh: 80vh;
    --top: 10vh;
    --left: 10vw;
    --cw: auto;
    --ch: auto;
    --cl: 0;
    --ct: 0;

    min-width:var(--cw);
    min-height:var(--ch);
    ._content {
        &._zoom-big {
            position: fixed;
            z-index: 999;
            width: var(--mw);
            height: var(--mh);
            top: var(--top);
            left: var(--left);
        }

        &._animate {
            animation-name: tobig;
            animation-fill-mode: forwards;
            animation-delay: .1s;
            animation-play-state: paused;
            animation-duration: .5s;
            animation-timing-function: ease-in-out;
        }

        ._operate{
            box-shadow:0px 0px 12px rgba(0, 0, 0, .12);
            .btn {
                color:#aaa;
                &:hover{
                    color:#333;
                }
            }
        }
    }

    ._place{
        width:var(--cw);
        height:var(--ch);
    }
}


@keyframes tobig {
    from {
        position: fixed;
        width: var(--cw);
        height: var(--ch);
        top: var(--ct);
        left: var(--cl);
        z-index: 999;
    }

    to {
        position: fixed;
        width: var(--mw);
        height: var(--mh);
        top: var(--top);
        left: var(--left);
        z-index: 999;
    }
}

/* // @keyframes clip {
//     from {
//         clip-path: circle(0%);
//     }

//     to {
//         clip-path: circle(100%);
//     }
// }

// @keyframes zoom {
//     from {
//         transform: scale(0)
//     }

//     to {
//         transform: scale(1)
//     }
// } */
</style>